import sys
import datetime
from types import NoneType
from types import ModuleType
from types import FunctionType
from types import BuiltinFunctionType
from typing import Any
from typing import Tuple
from typing import Mapping
from typing import TypeVar
from typing import Callable
from typing import ClassVar
from typing import Iterable
from typing import NoReturn

from _typeshed import SupportsItems

from .error import YAMLError as YAMLError
from .nodes import Node as Node
from .nodes import ScalarNode as ScalarNode
from .nodes import MappingNode as MappingNode
from .nodes import SequenceNode as SequenceNode

_T = TypeVar("_T")
_R = TypeVar("_R")

class RepresenterError(YAMLError): ...

class BaseRepresenter:
    yaml_representers: ClassVar[dict[type[Any], Callable[[BaseRepresenter, Any], Node]]]
    yaml_multi_representers: ClassVar[
        dict[type[Any], Callable[[BaseRepresenter, Any], Node]]
    ]
    default_style: str | Any
    sort_keys: bool
    default_flow_style: bool
    represented_objects: dict[int, Node]
    object_keeper: list[Any]
    alias_key: int | Any

    def __init__(
        self,
        default_style: str | None = ...,
        default_flow_style: bool = ...,
        sort_keys: bool = ...,
    ) -> None: ...
    def represent(self, data: Any) -> None: ...
    def represent_data(self, data: Any) -> Node: ...
    @classmethod
    def add_representer(
        cls: type[_R], data_type: type[_T], representer: Callable[[_R, _T], Node]
    ) -> None: ...
    @classmethod
    def add_multi_representer(
        cls: type[_R], data_type: type[_T], representer: Callable[[_R, _T], Node]
    ) -> None: ...
    def represent_scalar(
        self, tag: str, value: Any, style: str | None = ...
    ) -> ScalarNode: ...
    def represent_sequence(
        self, tag: str, sequence: Iterable[Any], flow_style: bool | None = ...
    ) -> SequenceNode: ...
    def represent_mapping(
        self,
        tag: str,
        mapping: SupportsItems[Any, Any] | Iterable[Tuple[Any, Any]],
        flow_style: bool | None = ...,
    ) -> MappingNode: ...
    def ignore_aliases(self, data: Any) -> bool: ...

class SafeRepresenter(BaseRepresenter):
    inf_value: ClassVar[float]

    def represent_none(self, data: NoneType) -> ScalarNode: ...
    def represent_str(self, data: str) -> ScalarNode: ...

    if sys.version_info < (3, 0): ...

    def represent_binary(self, data: bytes) -> ScalarNode: ...
    def represent_bool(self, data: bool) -> ScalarNode: ...
    def represent_int(self, data: int) -> ScalarNode: ...
    def represent_float(self, data: float) -> ScalarNode: ...
    def represent_list(self, data: Iterable[Any]) -> SequenceNode: ...
    def represent_dict(
        self, data: SupportsItems[Any, Any] | Iterable[Tuple[Any, Any]]
    ) -> MappingNode: ...
    def represent_set(self, data: Iterable[Any]) -> MappingNode: ...
    def represent_date(self, data: datetime.date) -> ScalarNode: ...
    def represent_datetime(self, data: datetime.datetime) -> ScalarNode: ...
    def represent_yaml_object(
        self, tag: str, data: Any, cls: type[Any], flow_style: bool | None = ...
    ) -> MappingNode: ...
    def represent_undefined(self, data: Any) -> NoReturn: ...

class Representer(SafeRepresenter):
    if sys.version_info < (3, 0): ...

    def represent_complex(self, data: complex) -> ScalarNode: ...
    def represent_tuple(self, data: Iterable[Any]) -> SequenceNode: ...
    def represent_name(
        self, data: BuiltinFunctionType | FunctionType
    ) -> ScalarNode: ...
    def represent_module(self, data: ModuleType) -> ScalarNode: ...
    def represent_object(self, data: object) -> SequenceNode | MappingNode: ...
    def represent_ordered_dict(self, data: Mapping[Any, Any]) -> SequenceNode: ...
